package com.guanghua.brick.biz.extend.spring;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.RootBeanDefinition;
import org.springframework.beans.factory.xml.BeanDefinitionParser;
import org.springframework.beans.factory.xml.ParserContext;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import com.guanghua.brick.util.FileUtil;

/**
 * User: Urubatan Date: 27/10/2006 Time: 17:07:35
 */
public class AnnotationAutoloadBeanDefinitionParser implements BeanDefinitionParser {
	
	private static Log logger = LogFactory.getLog(AnnotationAutoloadBeanDefinitionParser.class);
	
	public BeanDefinition parse(Element element, ParserContext parserContext) {
		String pattern = element.getAttribute("pattern");
		
		//解析配置
		List<String> packages = new ArrayList<String>();
		NodeList childNodes = element.getChildNodes();
		for (int i = 0; i < childNodes.getLength(); i++) {
			Node node = childNodes.item(i);
			if (node.getNodeType() == Node.ELEMENT_NODE) {
				String localName = node.getLocalName();
				if ("package".equals(localName)) {
					packages.add(node.getTextContent());
				}
			}
		}
		
		
		//寻找类
		Iterator<String> i = packages.iterator();
		List<String> files = new ArrayList<String>();
		if (pattern == null) pattern = ".*\\.class";
		while (i.hasNext()) {
			String pkg = i.next();
			if (pkg.indexOf('.') != -1) pkg = pkg.replace('.', '/');
			try {
				logger.debug("find spring bean package:" + pkg);
				List<String> l = FileUtil.searchFileFromClassPath(pkg, pattern);
				logger.debug("find spring bean package result:" + l);
				files.addAll(l);
			} catch (Exception e) {
				logger.error("search spring bean package error:" + pkg, e);
			}
		}
		
		//加载类，获取bean id
		i = files.iterator();
		BeanDefinitionRegistry bdr = parserContext.getRegistry();
		while (i.hasNext()) {
			String clsName = i.next();
			//logger.debug("deal spring bean class name:" + clsName);
			clsName = clsName.substring(0, clsName.length() - 6);
			clsName = clsName.replace('/', '.');
			//logger.debug("deal spring bean class name result:" + clsName);
			
			try {
				//获取bean id
				Class<?> c = Class.forName(clsName);
				Bean bean = (Bean)c.getAnnotation(Bean.class);
				
				//如果被注释成spring bean
				if (bean != null) {
					String id = bean.id();
					logger.debug("spring bean class " + clsName + "'s id is " + id);
					
					//加载
					final RootBeanDefinition rbd = new RootBeanDefinition();
					rbd.setAbstract(false);
					rbd.setBeanClass(c);
					rbd.setSingleton(false);
					rbd.setLazyInit(false);				
					
					bdr.registerBeanDefinition(id, rbd);
				}
			} catch (ClassNotFoundException e) {
				logger.error("find class wrong:" + clsName, e);
			}
		}
		
		return null;
	}
}
